package com.glodon.spring.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.aliyun.openservices.ons.api.SendResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.glodon.spring.enty.BulletinEntity;
import com.glodon.spring.service.BulletinService;
import com.glodon.utils.dto.DataTableJson;
import com.glodon.utils.dto.PageableDto;
import com.glodon.utils.service.MessageSendService;
import com.glodon.utils.service.StringRedisService;
import com.glodon.utils.util.*;

/**
 * Created by Administrator on 2017-4-5.
 */
@Controller
public class MainController {

    private static final Logger log = LoggerFactory.getLogger(MainController.class);

    @Autowired
    private BulletinService bulletinService;

    @Autowired
    private StringRedisService redisService;

    @Autowired
    private MessageSendService messageSendService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    private ModelAndView index(Model model) {

        try {
            String key = redisService.get("key");
            log.info("缓存key:{}" , key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ModelAndView mv = new ModelAndView("/view/login");
        return mv;
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    private ModelAndView index1(Model model) {

        ModelAndView mv = new ModelAndView("/view/index");
        return mv;
    }

    @RequestMapping(value = "/faceAPI", method = RequestMethod.POST)
    @ResponseBody
    private ResponseParam faceAPI(String filePath) {

        ResponseParam responseParam = ResponseParam.success() ;

//        File file = new File(filePath);
//        byte[] buff = ImageToTextUtil.getBytesFromFile(file);
        List<JSONArray> list = ImageToTextUtil.tesseractText_face(filePath);

        List anaylizeList = ImageToTextUtil.anaylizeList(list);

        responseParam.addData(list.toString());

        return responseParam;
    }

    @RequestMapping(value = "/tesseract", method = RequestMethod.POST)
    @ResponseBody
    private ResponseParam tesseract(String filePath) {

        ResponseParam responseParam = ResponseParam.success() ;

        try{

//            InputStream inputStream = ImgCompress.cleanImage(filePath);

            InputStream inputStream = new FileInputStream(new File(filePath));

            String str = ImageToTextUtil.tesseract(inputStream);

            responseParam.addParam("data", str);

        }catch (Exception e) {
            e.printStackTrace();
        }

        return responseParam;
    }
    @RequestMapping(value = "/echart", method = RequestMethod.GET)
    private ModelAndView echart(Model model) {

        ModelAndView mv = new ModelAndView("/view/echart");
        return mv;
    }

    @RequestMapping(value = "/tag", method = RequestMethod.GET)
    private ModelAndView tag(Model model) {
        ModelAndView mv = new ModelAndView("/view/first");
        return mv;
    }

    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    private ResponseParam first(@RequestParam(required=true,defaultValue="1") Integer page,
                               @RequestParam(required=false,defaultValue="10") Integer pageSize) {

        ResponseParam responseParam = ResponseParam.success() ;

        PageHelper.startPage(page, pageSize);
        List<BulletinEntity> list = bulletinService.query();
        PageInfo<BulletinEntity> p=new PageInfo<>(list);

        log.info("AOP日志:{}" , list.size());

        try {
            redisService.setExpire("key", list.get(0).toString(), 10);
        } catch (Exception e) {
            e.printStackTrace();
        }

        responseParam.put("page", p);
        return responseParam;
    }

    @RequestMapping(value = "/datatable", method = RequestMethod.POST)
    @ResponseBody
    private DataTableJson datatable(HttpServletRequest request,
                             @RequestParam(required=false,defaultValue="10") Integer pageSize) {

        // 获取bootstrap dataTable 的一些请求参数
        DataTableParameter dataTableParameter = DataTableUtils.getDataTableParameter(request);
        // 当前页码，可能哪里有错误，页码不是特别对头
        int page = dataTableParameter.getiDisplayStart()/10 + 1;
        // PageHelper：mybatis的分页插件
        PageHelper.startPage(page, pageSize);
        // 当前页面的数据源
        List<BulletinEntity> list = bulletinService.query();
        PageInfo<BulletinEntity> p=new PageInfo<>(list);

        // JSON 的元数据
        PageableDto ret = new PageableDto();
        ret.setSuccess(true);
        // 当前页码
        ret.setPage(page);
        // 所有记录数，实际需要单独取数据库总数
        ret.setTotalCounts((int) p.getTotal());
        // 每页大小
        ret.setSize(pageSize);
        // 数据源
        ret.setData(list);

        // 返回JSON数据源
        return Dto2DataTablesUtils.dto2DataTableJson(ret, dataTableParameter.getsEcho());
    }

    @RequestMapping(value = "/sendMsg", method = RequestMethod.POST)
    @ResponseBody
    private SendResult sendMsg(@RequestParam(required=false,defaultValue="") String id) throws IOException {

        // 当前页面的数据源
        BulletinEntity bulletinEntity = bulletinService.queryById(id);

        SendResult sendResult = messageSendService.sendMessage("test", JSON.toJSONString(bulletinEntity));

        log.info("消息队列key：{}", sendResult.getMessageId());

        return sendResult;
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    private ResponseParam login(HttpServletRequest request,
                                @RequestParam(required=false,defaultValue="") String username,
                                @RequestParam(required=false,defaultValue="") String password,
                                @RequestParam(required=false,defaultValue="") String code){

        HttpSession session = request.getSession(false);

        ResponseParam responseParam = ResponseParam.success() ;

        try {
            String sessionCode = redisService.get(session.getId());
            if (!StringUtils.equals(code.toUpperCase(), sessionCode.toUpperCase())) {
                log.info("对用户[" + username + "]进行验证码验证。。。错误");
                responseParam.put("message" , "验证码错误。") ;
            } else {
                UsernamePasswordToken token = new UsernamePasswordToken(username, password);
                token.setRememberMe(true);
                //获取当前的Subject
                Subject currentUser = SecurityUtils.getSubject();
                try {
                    //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
                    //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
                    //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
                    log.info("对用户[" + username + "]进行登录验证..验证开始");
                    currentUser.login(token);
                    log.info("对用户[" + username + "]进行登录验证..验证通过");
                }catch(Exception uae){
                    log.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
                    request.setAttribute("message_login", "未知账户");
                    responseParam.put("message" , "登录失败。") ;
                }
                //验证是否登录成功
                if(currentUser.isAuthenticated()){
                    log.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
                }else{
                    responseParam.put("message" , "验证失败。") ;
                    token.clear();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return responseParam;
    }

    /**
     * 用户登出
     */
    @RequestMapping("/logout")
    public String logout(HttpServletRequest request){
        SecurityUtils.getSubject().logout();
        return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";
    }
}
